﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace GeoPal
{
    /// <summary>
    /// Application logic of the formSettings form
    /// </summary>
    public partial class formSettings : Form
    {
        /// <summary>
        /// Local settings directory
        /// </summary>
        readonly string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GeoPal";
        /// <summary>
        /// Local settings file path
        /// </summary>
        readonly string filepath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GeoPal\\settings.xml";
        /// <summary>
        /// Used Settings object
        /// </summary>
        Settings settings;
        /// <summary>
        /// Constructor of the formSettings class (initializes default values)
        /// </summary>
        /// <param name="_settings">Used Settings object</param>
        public formSettings(ref Settings _settings)
        {
            InitializeComponent();
            /* Construct COM port list */
            foreach (string s in System.IO.Ports.SerialPort.GetPortNames())
            {
                cbPort.Items.Add(s);
            }
            /* Construct baud and update values */
            int[] bauds = new int[] { 57600, 38400, 19200, 9600, 4800 };
            int[] intervals = new int[] { 5, 10, 30, 60, 120, 180 };
            int[] distances = new int[] { 0, 5, 15, 30, 100, 500, 1500 };
            /* Construct Google map types */
            string[] maptypes = new string[] { "mobile", "roadmap", "satellite", "terrain", "hybrid"};
            foreach (int i in bauds)
            {
                cbBaud.Items.Add(i.ToString());
            }
            foreach (int i in intervals)
            {
                cbUpdateInterval.Items.Add(i.ToString());
                cbRequestInterval.Items.Add(i.ToString());
            }
            foreach (int i in distances)
            {
                cbUpdateDistance.Items.Add(i.ToString());
            }
            foreach (string s in maptypes)
            {
                cbGoogleMapType.Items.Add(s);
            }
            /* Fill the components from the settings file */
            formSettings_Load(this, null);
            /* Update the settings object */
            _settings = settings;
        }
        /// <summary>
        /// Fill the components when the form loads
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Event arguments</param>
        private void formSettings_Load(object sender, EventArgs e) {
            /* Create new XMLSerializer object */
            XmlSerializer ser = new XmlSerializer(typeof(Settings));
            /* Check if the configuration directory exists */
            if (!Directory.Exists(dir))
            {
                /* If not, creating one */
                Directory.CreateDirectory(dir);
            }
            /* Check if the configuration file exists */
            if (File.Exists(filepath)) {
                /* If exists, open it and deserialize to the settings object */
                FileStream fs = new FileStream(filepath, FileMode.Open);
                settings = (Settings)ser.Deserialize(fs);
                fs.Close();

                /* Fill the form fields with the configuration data */
                tbUsername.Text = settings.UserName;
                tbPassword.Text = settings.UserPass;
                tbServer.Text = settings.ServerUrl;
                cbPort.Text = settings.Port;
                cbBaud.Text = settings.Baud.ToString();
                cbRequestInterval.Text = settings.RequestInterval.ToString();
                cbUpdateInterval.Text = settings.UpdateInterval.ToString();
                cbUpdateDistance.Text = settings.UpdateDistance.ToString();
                cbGoogleMapType.Text = settings.GoogleMapType;
                tbApiKey.Text = settings.GoogleApiKey;
                chbIsLogged.Checked = settings.IsLogged;
                chbEnergySave.Checked = settings.IsEnergySave;
                tbTwitterName.Text = settings.TwitterName;
                tbTwitterPass.Text = settings.TwitterPass;
            } else {
                /* If not, create one and fill it with the settings object */
                FileStream fs = new FileStream(filepath, FileMode.CreateNew);
                TextWriter tw = new StreamWriter(fs);
                settings = new Settings();
                ser.Serialize(tw, settings);
                tw.Close();
                fs.Close();
            } 
        }
        /// <summary>
        /// Serialize the data when form closes
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Event arguments</param>
        private void formSettings_Closed(object sender, EventArgs e)
        {
            try
            {
                settings.UserName = tbUsername.Text;
                settings.UserPass = tbPassword.Text;
                settings.ServerUrl = tbServer.Text;
                settings.Port = cbPort.Text;
                settings.Baud = Convert.ToUInt32(cbBaud.Text);
                settings.UpdateInterval = Convert.ToInt32(cbUpdateInterval.Text);
                settings.RequestInterval = Convert.ToInt32(cbRequestInterval.Text);
                settings.UpdateDistance = Convert.ToInt32(cbUpdateDistance.Text);
                settings.GoogleApiKey = tbApiKey.Text;
                settings.GoogleMapType = cbGoogleMapType.Text;
                settings.IsLogged = chbIsLogged.Checked;
                settings.IsEnergySave = chbEnergySave.Checked;
                settings.TwitterName = tbTwitterName.Text;
                settings.TwitterPass = tbTwitterPass.Text;

                XmlSerializer ser = new XmlSerializer(typeof(Settings));
                TextWriter tw = new StreamWriter(filepath, false);
                ser.Serialize(tw, settings);
                tw.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                System.Windows.Forms.MessageBox.Show("Invalid data format!");
            }

        }
        /// <summary>
        /// Validate fields before closing the form
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Event arguments</param>
        private void menuItemExit_Click(object sender, EventArgs e)
        {
            /* Format check */
            if (String.IsNullOrEmpty(tbUsername.Text) || String.IsNullOrEmpty(tbPassword.Text))
            {
                System.Windows.Forms.MessageBox.Show("You must specify username and password!");
            }
            else if (!System.Uri.IsWellFormedUriString(tbServer.Text, UriKind.Absolute))
//            else if(String.IsNullOrEmpty(tbServer.Text))
            {
                System.Windows.Forms.MessageBox.Show("Invalid server address!");
            }
            else if (String.IsNullOrEmpty(cbPort.Text) || String.IsNullOrEmpty(cbBaud.Text))
            {
                System.Windows.Forms.MessageBox.Show("You must configure the GPS receiver!");
            }
            else if (String.IsNullOrEmpty(tbApiKey.Text))
            {
                System.Windows.Forms.MessageBox.Show("You must specify a Google API key!");
            }
            else if (String.IsNullOrEmpty(cbRequestInterval.Text) || String.IsNullOrEmpty(cbUpdateDistance.Text) || String.IsNullOrEmpty(cbUpdateInterval.Text))
            {
                System.Windows.Forms.MessageBox.Show("Invalid update interval!");
            }
            else
            {
                this.Close();
            }
        }
    }
}